home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Linux Cubed Series 7: Sunsite
/
Linux Cubed Series 7 - Sunsite Vol 1.iso
/
system
/
filesyst
/
thsfs.tgz
/
thsfs.tar
/
thsfs
/
kompr.c
< prev
next >
Wrap
C/C++ Source or Header
|
1994-10-04
|
4KB
|
218 lines
/*************************************************************
* *
* ths Filesystem 04.10.94 V1.1 *
* *
* Thomas Scheuermann ths@ai-lab.fh-furtwangen.de *
* *
*************************************************************/
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/sched.h>
#include <linux/errno.h>
#include <linux/string.h>
#include <linux/stat.h>
#include <linux/mm.h>
#include <linux/locks.h>
#include <linux/fs.h>
#include <linux/malloc.h>
#include <asm/system.h>
#include <asm/segment.h>
#include <asm/bitops.h>
#include "ths.h"
#include "ths_i.h"
/*
* Test auf 44530002
*/
int arttest(long *data)
{
if(*data == 0x02005344)
return 0;
else
return 1;
}
/*
* Daten holen
*/
void nextdata(unsigned char **data, int *bz, int *cc,long *zc,struct super_block *s,long sektor, struct buffer_head **bh)
{
while(*bz < 25)
{
if (!(*cc % 512))
*data = ths_uread(s,sektor+(*cc)/512,bh);
*zc |= (unsigned long)(*data)[*cc%512]<<*bz;
(*cc)++;
if (!(*cc % 512))
brelse(*bh);
*bz +=8;
}
}
/*
* Dekompressionsalgorithmus
* funktioniert nur mit Komprimierung 2
*/
void decompress(struct super_block *s, struct ths_buffer *tbf, int mdfat)
{
unsigned char zu,flag,*data=NULL;
unsigned long sektor,zc;
struct buffer_head *bh;
int k,rb,rl,hz,m,sek,sekmax,bz,cc,test;
#ifdef DEBUG
printk("decompress %d\n",mdfat);
#endif
sektor = (mdfat & 0x1fffff) +1;
sekmax = ((mdfat & 0x3c000000)>>26) +1;
/*
* i : Bitzaehler
* k : Zeichenzaehler dekomprimiert
* hz : Hilfszaehler fuer Bits;
* rb : Rueckwaertsbezug rb Bytes
* rl : Laenge des Rueckwaertsbezugs
* m : Laengenhilfsspeicher
* flag : Status
* zc : komprimierte Daten(max 4 Byte)
* bz : Bitzaehler fuer zc
* cc : Zeichenzaehler fuer unkomprimierte Zeichen
* zu : unkomprimiertes Zeichen
* sek : Sektorzaehler
*/
k=0;
zu=0;
zc=0;
rb=0;
rl=0;
hz=0;
m=0;
sek = 0;
flag = 'n';
bz=0;
cc=0;
test=0;
nextdata(&data,&bz,&cc,&zc,s,sektor,&bh);
if(arttest(&zc))
{
printk("Komprimierung nicht erkannt !\n");
return;
}
zc=0;
bz=0;
nextdata(&data,&bz,&cc,&zc,s,sektor,&bh);
for(;sek<sekmax;)
{
switch(zc&0x03)
{
case 2: /* 0 - 127 */
zc>>=2;
zu = (unsigned char)zc & 0x7f;
zc>>=7;
bz -=9;
(tbf->data[k/512])[k%512] = zu;
k++;
if(bz<17)
nextdata(&data,&bz,&cc,&zc,s,sektor,&bh);
break;
case 1: /* 128 - 255 */
zc>>=2;
zu = (unsigned char)(zc & 0x7f)|128;
zc>>=7;
bz -=9;
(tbf->data[k/512])[k%512] = zu;
k++;
if(bz<17)
nextdata(&data,&bz,&cc,&zc,s,sektor,&bh);
break;
case 0: /* 6 Bit Rueckbezug */
zc>>=2;
rb = zc & 0x3f;
zc>>=6;
bz -=8;
if(bz<17)
nextdata(&data,&bz,&cc,&zc,s,sektor,&bh);
hz=0;
for(;!(zc&0x01);zc>>=1,hz++);
zc>>=1;
bz-=(hz+1);
rl = (zc & ((1<<hz)-1)) + (1<<hz)+1;
zc>>=hz;
bz -=hz;
if(bz<17)
nextdata(&data,&bz,&cc,&zc,s,sektor,&bh);
for(hz=0;hz<rl;hz++)
{
(tbf->data[k/512])[k%512] = (tbf->data[(k-rb)/512])[(k-rb)%512];
k++;
}
break;
case 3: /* Rueckbezug auf 65+ oder 320+ Zeichen */
switch(zc&0x07)
{
case 3: /* 65+ Zeichen */
zc>>=3;
rb = (zc & 0xff) + 64;
zc>>=8;
bz -=11;
break;
case 7: /* 320+ Zeichen */
zc>>=3;
rb = (zc & 0xfff);
if(rb == 0xfff)
test=1;
rb+=320;
zc>>=12;
bz -=15;
break;
}
if(bz<17)
nextdata(&data,&bz,&cc,&zc,s,sektor,&bh);
if(test)
{
test=0;
sek++;
break; /* Sonderfall 512 Byte Grenze */
}
hz=0;
for(;!(zc&0x01);zc>>=1,hz++);
zc>>=1;
bz-=(hz+1);
rl = (zc & ((1<<hz)-1)) + (1<<hz)+1;
zc>>=hz;
bz -=hz;
if(bz<17)
nextdata(&data,&bz,&cc,&zc,s,sektor,&bh);
for(hz=0;hz<rl;hz++)
{
(tbf->data[k/512])[k%512] = (tbf->data[(k-rb)/512])[(k-rb)%512];
k++;
}
break;
}
}
if((cc%512))
{
brelse(bh);
}
#ifdef DEBUG
printk("decompress Ende\n");
#endif
return;
}